/* SPDX-License-Identifier: GPL-2.0-or-later
 *
 *
 * Copyright (C) 2016-2018, LomboTech Co.Ltd.
 * Authors:
 *	lomboswer <lomboswer@lombotech.com>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */


#ifndef __CSP_DOSS_TOP_H__
#define __CSP_DOSS_TOP_H__

#define DOSS_MAX_INST (2)

#define DOSS_TOP0	 (0)
#define DOSS_TOP1	 (1)

/* doss top register offset */
#define DOSS_PATH_SIZE			        (0x020)
#define DOSS_REG_SIZE			        (0x004)

#define DOSS_TOP_VER_OFF			(0x000)
#define DOSS_TOP_DO0_FTR_OFF			(0x010)
#define DOSS_TOP_DO1_FTR_OFF			(0x014)
#define DOSS_TOP_RESET_OFF			(0x020)
#define DOSS_ROUTE_OFF				(0x024)
#define DOSS_INTF0_LDO_CTRL_OFF			(0x030)
#define DOSS_INTF1_LDO_CTRL_OFF			(0x034)
#define DOSS_LVDS_INTF0_LDO_CTRL_OFF	        (0x030)
#define DOSS_LVDS_INTF1_LDO_CTRL_OFF	        (0x034)
#define DOSS_DPHY_INTF0_LDO_CTRL_OFF	        (0x038)
#define DOSS_DPHY_INTF1_LDO_CTRL_OFF	        (0x03C)
#define DOSS_TCON_CTRL_OFF			(0x100)
#define DOSS_TCON_CLK_OFF			(0x104)
#define DOSS_LVDS_CTRL_OFF			(0x140)
#define DOSS_LVDS_CLK_OFF			(0x144)
#define DOSS_MIPI_DSI_CTRL_OFF			(0x180)
#define DOSS_MIPI_DSI_REF_CLK_OFF		(0x184)
#define DOSS_MIPI_DSI_CFG_CLK_OFF		(0x188)

#define DOSS_EDP_CTRL_OFF			(0x1C0)
#define DOSS_EDP_REF_CLK_OFF			(0x1C4)
#define DOSS_EDP_AUX_CLK_OFF			(0x1C8)

#define DOSS_CSI_TX_CTRL_OFF			(0x200)
#define DOSS_CSI_TX_CLK_OFF			(0x204)
#define DOSS_CSI_TX_CLK_GAT_OFF			(0x208)

#define DOSS_TVE_CTRL_OFF			(0x400)
#define DOSS_TVE_CLK_OFF			(0x404)

#define DOSS_HDMI_CTRL_OFF			(0x440)
#define DOSS_HDMI_REF_CLK_OFF			(0x444)
#define DOSS_HDMI_SFR_CLK_OFF			(0x448)
#define DOSS_HDMI_CEC_CLK_OFF			(0x44C)

#define DOSS_VGA_CTRL_OFF			(0x480)
#define DOSS_VGA_CLK_OFF			(0x484)
/* register end */

#define DOSS_ONE_ROAD_ONE_ROUTE			(0x1100)
#define DOSS_ONE_ROAD_MULTI_ROUTE		(0x1101)
#define DOSS_TWO_ROAD_ONE_ROUTE		        (0x1200)
#define DOSS_TWO_ROAD_MULTI_ROUTE		(0x1201)

#define DPU_DC0					(0x0)
#define DPU_DC1				        (0x1)
#define DPU_DC2					(0x2)
#define TCON_DIO0				(0x0)
#define TCON_DIO1				(0x1)

#define DOSS_CLK_ON				(1)
#define DOSS_CLK_OFF				(0)
#define DOSS_CTRL_ON				(1)
#define DOSS_CTRL_OFF				(0)

#define DOSS_CLK_DIV_MAX0			(16)
#define DOSS_CLK_DIV_MAX1			(2)
#define DOSS_CLK_PARENT_MAX			(1)

typedef enum doss_ctrl_id {
	DOSS_CTRL_TCON			= DOSS_TCON_CTRL_OFF,
	DOSS_CTRL_LVDS			= DOSS_LVDS_CTRL_OFF,
	DOSS_CTRL_MIPI_DSI		= DOSS_MIPI_DSI_CTRL_OFF,
	DOSS_CTRL_EDP			= DOSS_EDP_CTRL_OFF,
	DOSS_CTRL_CSI_TX                = DOSS_CSI_TX_CTRL_OFF,
	DOSS_CTRL_TVE			= DOSS_TVE_CTRL_OFF,
	DOSS_CTRL_HDMI			= DOSS_HDMI_CTRL_OFF,
	DOSS_CTRL_VGA			= DOSS_VGA_CTRL_OFF,
} doss_ctrl_id_t;

typedef enum doss_clk_id {
	DOSS_CLK_TCON			= DOSS_TCON_CLK_OFF,
	DOSS_CLK_LVDS			= DOSS_LVDS_CLK_OFF,
	DOSS_CLK_MIPI_DSI_REF		= DOSS_MIPI_DSI_REF_CLK_OFF,
	DOSS_CLK_MIPI_DSI_CFG		= DOSS_MIPI_DSI_CFG_CLK_OFF,
	DOSS_CLK_EDP_REF		= DOSS_EDP_REF_CLK_OFF,
	DOSS_CLK_EDP_AUX		= DOSS_EDP_AUX_CLK_OFF,
	DOSS_CLK_CSI_TX			= DOSS_CSI_TX_CLK_OFF,
	DOSS_CLK_CSI_TX_GAT		= DOSS_CSI_TX_CLK_GAT_OFF,
	DOSS_CLK_TVE			= DOSS_TVE_CLK_OFF,
	DOSS_CLK_HDMI_REF		= DOSS_HDMI_REF_CLK_OFF,
	DOSS_CLK_HDMI_SFR		= DOSS_HDMI_SFR_CLK_OFF,
	DOSS_CLK_HDMI_CEC		= DOSS_HDMI_CEC_CLK_OFF,
	DOSS_CLK_VGA			= DOSS_VGA_CLK_OFF,
} doss_clk_id_t;

typedef enum doss_clk_src {
	DOSS_CLK_HFEOSC	= 0x0, /* TODO */
	DOSS_CLK_SCLK0	= 0x1, /* TODO */
	DOSS_CLK_SCLK1	= 0x2, /* TODO */
	DOSS_CLK_SCLK2	= 0x3, /* TODO */
} doss_clk_src_t;

typedef enum doss_dpu_src {
	DOSS_SRC_DC0	= DPU_DC0,
	DOSS_SRC_DC1	= DPU_DC1,
	DOSS_SRC_DC2	= DPU_DC2,
} doss_dpu_src_t;

typedef enum doss_tcon_idx {
	DOSS_TCON0	= 0x0,
	DOSS_TCON1	= 0x1,
	DOSS_TCON2	= 0x2,
} doss_tcon_idx_t;

typedef enum doss_rgb_if {
	DOSS_VO_RGB0	= TCON_DIO0,
	DOSS_VO_RGB1	= TCON_DIO1,
} doss_rgb_if_t;

typedef enum doss_tcon_dio_route {
	DOSS_TCON0_DIO0_AND_TCON1_DIO1,
	DOSS_TCON0_DIO0_AND_TCON2_DIO1,
	DOSS_TCON0_DIO1_AND_TCON1_DIO0,
	DOSS_TCON0_DIO1_AND_TCON2_DIO0,

	DOSS_TCON1_DIO0_AND_TCON2_DIO1,
	DOSS_TCON1_DIO1_AND_TCON2_DIO0,
} doss_tcon_dio_route_t;

typedef enum doss_dc_tcon_route {
	/* signal/dual/triple tcon different display */
	DOSS_DC0_TCON0_AND_DC1_TCON1_AND_DC2_TCON2 = 0,
	DOSS_DC0_TCON0_AND_DC1_TCON2_AND_DC2_TCON1,
	DOSS_DC0_TCON1_AND_DC1_TCON0_AND_DC2_TCON2,
	DOSS_DC0_TCON1_AND_DC1_TCON2_AND_DC2_TCON0,
	DOSS_DC0_TCON2_AND_DC1_TCON0_AND_DC2_TCON1,
	DOSS_DC0_TCON2_AND_DC1_TCON1_AND_DC2_TCON0,

	/* triple tcon the same display */
	DOSS_DC0_TCON0_TCON1_TCON2,
	DOSS_DC1_TCON0_TCON1_TCON2,
	DOSS_DC2_TCON0_TCON1_TCON2,

	/* dual tcon the same display and signal tcon different display */
	DOSS_DC0_TCON0_TCON1_AND_DC1_TCON2,
	DOSS_DC0_TCON0_TCON2_AND_DC1_TCON1,
	DOSS_DC0_TCON1_TCON2_AND_DC1_TCON0,

	DOSS_DC1_TCON1_TCON2_AND_DC0_TCON0,
	DOSS_DC1_TCON0_TCON1_AND_DC0_TCON2,
	DOSS_DC1_TCON0_TCON2_AND_DC0_TCON1,

	DOSS_DC0_TCON0_TCON1_AND_DC2_TCON2,
	DOSS_DC0_TCON0_TCON2_AND_DC2_TCON1,
	DOSS_DC0_TCON1_TCON2_AND_DC2_TCON0,

	DOSS_DC2_TCON1_TCON2_AND_DC0_TCON0,
	DOSS_DC2_TCON0_TCON1_AND_DC0_TCON2,
	DOSS_DC2_TCON0_TCON2_AND_DC0_TCON1,

	DOSS_DC1_TCON0_TCON1_AND_DC2_TCON2,
	DOSS_DC1_TCON0_TCON2_AND_DC2_TCON1,
	DOSS_DC1_TCON1_TCON2_AND_DC2_TCON0,

	DOSS_DC2_TCON1_TCON2_AND_DC1_TCON0,
	DOSS_DC2_TCON0_TCON1_AND_DC1_TCON2,
	DOSS_DC2_TCON0_TCON2_AND_DC1_TCON1,
} doss_dc_tcon_route_t;

void csp_doss_set_register_base(u32 doss_idx, void *addr, u32 size);
void csp_doss_get_register_base(u32 doss_idx, unsigned long *addr);
void csp_doss_init(u32 doss_idx);
void csp_doss_exit(u32 doss_idx);
s32 csp_doss_set_output_route(doss_tcon_dio_route_t output_route);
s32 csp_doss_set_input_route(doss_dc_tcon_route_t input_route);
bool csp_doss_clk_is_enable(u32 doss_idx, u32 path_id, doss_clk_id_t clk_id);
void csp_doss_clk_enable(u32 doss_idx, u32 path_id, doss_clk_id_t clk_id);
void csp_doss_clk_disable(u32 doss_idx, u32 path_id, doss_clk_id_t clk_id);
void csp_doss_clk_set(u32 doss_idx, u32 path_id, doss_clk_id_t clk_id,
	doss_clk_src_t src, u8 div0, u8 div1);
void csp_doss_clk_src_set(u32 doss_idx, u32 path_id,
	doss_clk_id_t clk_id, doss_clk_src_t src);
void csp_doss_path_enable(u32 doss_idx, u32 path_id, doss_ctrl_id_t ctrl_id);
void csp_doss_path_disable(u32 doss_idx, u32 path_id, doss_ctrl_id_t ctrl_id);
void csp_doss_slave_enable(u32 doss_idx, u32 path_id, doss_ctrl_id_t ctrl_id);
void csp_doss_slave_disable(u32 doss_idx, u32 path_id, doss_ctrl_id_t ctrl_id);
void csp_doss_phy_slave_enable(u32 doss_idx, u32 path_id,
	doss_ctrl_id_t ctrl_id);
void csp_doss_phy_slave_disable(u32 doss_idx, u32 path_id,
	doss_ctrl_id_t ctrl_id);
void csp_doss_dual_mode_enable(u32 doss_idx, u32 path_id,
	doss_ctrl_id_t ctrl_id);
void csp_doss_dual_mode_disable(u32 doss_idx, u32 path_id,
	doss_ctrl_id_t ctrl_id);
void csp_doss_path_init(u32 doss_idx, u32 path_id, doss_ctrl_id_t ctrl_id);
void csp_doss_path_rst(u32 doss_idx, u32 path_id, doss_ctrl_id_t ctrl_id);
void csp_doss_path_exit(u32 doss_idx, u32 path_id, doss_ctrl_id_t ctrl_id);
void csp_doss_vref_enable(u32 doss_idx, u32 intf_id, doss_ctrl_id_t ctrl_id);
void csp_doss_vref_disable(u32 doss_idx, u32 intf_id, doss_ctrl_id_t ctrl_id);
void csp_doss_io_set_output(u32 doss_idx, u32 func_id);
void csp_doss_io_set_val(u32 doss_idx, u32 func_id, u32 val);
#endif /* __CSP_DOSS_TOP_H__ */
